/*
  Programa GEFE - Gestión de eventos lúdicos.
  Copyright (C) 2010  Antonio Ramírez Marti

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "acolitoconsiga.h"
#include "ui_acolitoconsiga.h"

#include <QSqlRecord>
#include <QSqlQuery>
#include <QMessageBox>
#include <QSqlError>
#include <QFile>
#include <QFileDialog>
#include <QTextStream>
#include <QItemSelectionModel>
#include <QItemSelection>

AcolitoConsiga::AcolitoConsiga(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::AcolitoConsiga)
{
    ui->setupUi(this);
    setup();
}

AcolitoConsiga::~AcolitoConsiga()
{
    borraModelo();
    delete ui;
}

void AcolitoConsiga::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void AcolitoConsiga::setup()
{
    modelo=0;
    mapper=0;
    filtro=0;
    mapModo=0;
    preparaMostrarValidar();
    conectaInterfaz();
    setConectado(false);
}

void AcolitoConsiga::mostrarDialogoValidar(bool estado)
{
    ui->labelValidar->setHidden(!estado);
    ui->dniLine->setHidden(!estado);
    ui->validarButton->setHidden(!estado);
}

void AcolitoConsiga::nuevoArchivoNumeros()
{
    //Confirmar por parte del usuario

    if(QMessageBox::question(this,"Acolito - Consigna","Ha solicitado una nueva cola de numeros; esto eliminara todas las entradas de numeros de la actual lista.\nDesea continuar?",QMessageBox::Yes,QMessageBox::No,QMessageBox::Abort)==QMessageBox::Yes)
    {
        //Preguntar si desea guardar la lista en un archivo de texto
        if(QMessageBox::question(this,"Acolito - Consigna","Desea conservar la actual lista de numeros en un archivo de texto?",QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes)
        {
            QString nombreLista=QFileDialog::getSaveFileName(this,"Seleccione archivo de salida para la lista",QString(),"Archivos de texto (*.txt)");

            QFile archivoLista(nombreLista);
            QTextStream stream;

            if(!archivoLista.open(QFile::WriteOnly | QFile::Text))
            {
                QMessageBox::critical(this,"Acolito - Consigna","No se pudo abrir el archivo "+nombreLista+".\nSe cancela la operacion");
                return;
            }

            stream.setDevice(&archivoLista);
            for(int i=0;i<modelo->rowCount();i++)
                stream << modelo->record(i).value("numDNI").toString() << '|' << modelo->record(i).value("numero").toString()<< "\n";

            archivoLista.close();
        }

        //Eliminar la lista actual
        QSqlQuery query(QSqlDatabase::database("evento"));

        query.exec("DROP TABLE numeros_consigna");
        query.exec("CREATE TABLE numeros_consigna"
                   "("
                    "numDNI VARCHAR(9) UNIQUE NOT NULL,"
                    "numero INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL"
                   ")");

        modelo->select();
    }

}

void AcolitoConsiga::preparaMostrarValidar()
{
    //Ocultar los campos de edicion
    ui->labelValidar->setHidden(true);
    ui->dniLine->setHidden(true);
    ui->validarButton->setHidden(true);

    connect(ui->mostrarDialogoButton,SIGNAL(toggled(bool)),this,SLOT(mostrarDialogoValidar(bool)));
}

bool AcolitoConsiga::isConectado() const
{
    return flag_conectado;
}

void AcolitoConsiga::setConectado(bool estado)
{
    switch(estado)
    {
    case true:          //Conectar el acolito
        borraModelo();
        creaModelo();
        conectaModelo();
        break;
    case false:         // Desconectar el acolito
        borraModelo();
        break;
    }

    flag_conectado=estado;
}

void AcolitoConsiga::borraModelo()
{
    if(modelo)
    {
        delete modelo;
        modelo=0;
    }

    if(mapper)
    {
        delete mapper;
        mapper=0;
    }

    if(filtro)
    {
        delete filtro;
        filtro=0;
    }

    if(mapModo)
    {
        delete mapModo;
        mapModo=0;
    }
}

void AcolitoConsiga::creaModelo()
{
    modelo=new QSqlTableModel(this,QSqlDatabase::database("evento"));
    modelo->setTable("numeros_consigna");
    modelo->select();

    filtro=new QSortFilterProxyModel(this);
    filtro->setSourceModel(modelo);

    mapper=new QDataWidgetMapper(this);
    mapper->setModel(filtro);

    mapModo=new QSignalMapper(this);
}

void AcolitoConsiga::conectaModelo()
{
    ui->listView->setModel(filtro);
    ui->listView->setModelColumn(0);

    mapper->toFirst();
    mapper->addMapping(ui->dniLabel,0,"text");
    mapper->addMapping(ui->numberLabel,1,"text");

    connect(ui->listView->selectionModel(),SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),mapper,SLOT(setCurrentModelIndex(QModelIndex)));

    mapModo->setMapping(ui->setDniButton,0);
    mapModo->setMapping(ui->setNumerosButton,1);

    connect(ui->setDniButton,SIGNAL(toggled(bool)),mapModo,SLOT(map()));
    connect(ui->setNumerosButton,SIGNAL(toggled(bool)),mapModo,SLOT(map()));

    connect(mapModo,SIGNAL(mapped(int)),this,SLOT(setModo(int)));
}

void AcolitoConsiga::conectaInterfaz()
{
    connect(ui->validarButton,SIGNAL(clicked()),this,SLOT(nuevoNumero()));
    connect(ui->buscarLine,SIGNAL(textChanged(QString)),this,SLOT(buscarCadenaEnModelo(QString)));
}

void AcolitoConsiga::nuevoNumero()
{
    if(!isConectado() || ui->dniLine->text().isEmpty())      //O no esta conectado, o el valor de la linea no es el esperado
        return;

    QSqlQuery query(QSqlDatabase::database("evento"));
    QItemSelectionModel *modeloSeleccion;

    query.prepare("INSERT INTO numeros_consigna(numDNI) VALUES(:dni)");
    query.addBindValue(ui->dniLine->text());

    if(!query.exec())       // Puede que el DNI ya exista en la base de datos
    {
        QMessageBox *informacion;

        informacion=new QMessageBox(QMessageBox::Information,"Acolito - Consigna","No se pudo validar el DNI",QMessageBox::Ok,this);
        if(query.lastError().number()==19)
            informacion->setDetailedText("El DNI ya existe en el sistema y tiene un número asignado, por favor, búsquelo.");

        informacion->exec();
        delete informacion;
    }
    else
    {
        query.clear();
        query.exec("SELECT numero from numeros_consigna where numDNI='"+ui->dniLine->text().append("'"));
        query.first();
    }

    ui->buscarLine->setText(ui->dniLine->text());
    modelo->select();

    modeloSeleccion=ui->listView->selectionModel();

    QModelIndex primerElemento,segundoElemento;
    primerElemento=filtro->index(0,0);
    segundoElemento=filtro->index(0,1);
    QItemSelection seleccion(primerElemento,segundoElemento);
    modeloSeleccion->select(seleccion,QItemSelectionModel::Select);
    ui->listView->setSelectionModel(modeloSeleccion);
    ui->listView->setCurrentIndex(filtro->index(0,filtro->filterKeyColumn()));
    ui->dniLine->clear();
}

void AcolitoConsiga::setModo(int col)
{
    switch(col)
    {
    case 0:         // Buscar por DNI
        this->columnaBusqueda="numDNI=";
        filtro->setFilterKeyColumn(0);
        break;
    case 1:         // Buscar por numero asignado
        this->columnaBusqueda="numero=";
        filtro->setFilterKeyColumn(1);
        break;
    default:
        break;
    }

    ui->listView->setModelColumn(col);
    ui->buscarLine->clear();

}

int AcolitoConsiga::getModo() const
{
    return ui->listView->modelColumn();
}

void AcolitoConsiga::buscarCadenaEnModelo(QString cadena)
{
    /*
    if(cadena.isNull()|| cadena.isEmpty())
        modelo->setFilter(QString());
    else
        modelo->setFilter(columnaBusqueda+cadena.prepend("'").append("'"));
        */

    filtro->setFilterRegExp(cadena);
}
